package com.zlzlib.manager.controller;

import com.zlzlib.common.bean.*;
import com.zlzlib.log.bean.enums.LogType;
import com.zlzlib.log.config.LogOperation;
import com.zlzlib.manager.bean.dto.DoByIdDto;
import com.zlzlib.manager.bean.dto.DeleteByIdsDto;
import com.zlzlib.manager.exception.ConfigException;
import com.zlzlib.manager.service.BaseManagerService;
import com.zlzlib.mybatis.BasePo;
import com.zlzlib.vuePage.VuePageUtils;
import com.zlzlib.vuePage.bean.vo.EditDialogPageVo;
import io.swagger.annotations.ApiOperation;
import org.modelmapper.ModelMapper;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.Valid;
import java.lang.reflect.ParameterizedType;

/**
 * 管理页面控制器
 * ADD==前端传输的添加数据  UP==前端传输的更新数据
 *
 * @DateTime: 2024/5/22 16:00
 * @Author zlz
 * @Version 1.0
 */
@Validated
public abstract class BaseManagerController<PO extends BasePo, LV, FD extends PageDataDto
        , SER extends BaseManagerService<PO, LV, FD>, ADD, UP extends ADD>
        extends BaseFindController<PO, LV, FD, SER> {

    protected Class<ADD> addClazz = (Class<ADD>) ((ParameterizedType)
            getClass().getGenericSuperclass()).getActualTypeArguments()[4];

    public BaseManagerController(SER service, ModelMapper modelMapper) {
        super(service, modelMapper);
    }

    @ApiOperation(value = "获得修改查看弹窗页面配置数据")
    @LogOperation(type = LogType.operation)
    @GetMapping("/findDialogPageItem")
    @ResponseBody
    public ResultVo findDialogPageItem() {
        EditDialogPageVo vo = new EditDialogPageVo();
        vo.setForm(VuePageUtils.getFormItemList(addClazz));
        return ResultVo.success(vo);
    }

    @ApiOperation(value = "保存")
    @LogOperation(type = LogType.config)
    @PostMapping("/save")
    @ResponseBody
    public ResultVo save(@Valid @RequestBody ADD dto) {
        PO po = dtoToPo(dto);
        saveBefore(po);
        if (service.save(po)) {
            saveSuccess(po);
            return ResultVo.success("保存成功!");
        }
        return ResultVo.error("保存失败!");
    }

    @ApiOperation(value = "删除单个")
    @LogOperation(type = LogType.config)
    @PostMapping("/delete")
    @ResponseBody
    public ResultVo delete(@RequestBody @Valid DoByIdDto dto) {
        deleteBefore(dto);
        if (service.removeById(dto.getId())) {
            deleteSuccess(dto);
            return ResultVo.success("删除成功!");
        }
        return ResultVo.error("删除失败!");
    }

    @ApiOperation(value = "批量删除")
    @LogOperation(type = LogType.config)
    @PostMapping("/deleteList")
    @ResponseBody
    public ResultVo deleteList(@RequestBody @Valid DeleteByIdsDto dto) {
        if (service.removeByIds(dto.getIds())) {
            return ResultVo.success("删除成功!");
        }
        return ResultVo.error("删除失败!");
    }

    @ApiOperation(value = "修改")
    @LogOperation(type = LogType.config)
    @PostMapping("/update")
    @ResponseBody
    public ResultVo update(@RequestBody @Valid UP dto) {
        PO po = dtoToPo(dto);
        //判断修改的是否存在
        if (service.getById(po.getId()) == null) {
            return ResultVo.error("当前更新的数据不存在!");
        }
        updateBefore(po);
        if (service.updateById(po)) {
            updateSuccess(po);
            return ResultVo.success("更新成功!");
        }
        return ResultVo.error("更新失败!");
    }

    @ApiOperation(value = "通过id查询当前数据")
    @LogOperation(type = LogType.operation)
    @PostMapping("/getDataById")
    @ResponseBody
    public ResultVo getDataById(@RequestBody @Valid DoByIdDto dto) {
        LV lv = service.findDataById(dto.getId());
        if (lv == null) {
            return ResultVo.error("获取数据失败!");
        }
        return ResultVo.success(lv);
    }


    protected PO dtoToPo(ADD dto) {
        PO po = modelMapper.map(dto, poClazz);
        dtoToPo(po, dto);
        return po;
    }

    /**
     * 转化特殊数据
     *
     * @param po  数据库实体
     * @param dto 添加实体
     */
    protected abstract void dtoToPo(PO po, ADD dto);

    protected void saveBefore(PO po) throws ConfigException {
    }

    protected void saveSuccess(PO po) throws ConfigException {
    }

    protected void updateBefore(PO po) throws ConfigException {
    }

    protected void updateSuccess(PO po) throws ConfigException {
    }

    protected void deleteBefore(DoByIdDto dto) throws ConfigException {
    }

    protected void deleteSuccess(DoByIdDto dto) throws ConfigException {
    }
}
